﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinacor.Infra.Core.ProcessManager.Server.Configuration;
using Sinacor.Infra.Service.Security;

namespace Sinacor.Infra.Core.ProcessManager.Server.Security
{
    /// <summary>
    /// Classe responsável pela criação dos dados de Authorização do Sinacor
    /// </summary>
    internal class SinacorAuthenticationDataBuilder
    {
        private static class DataKeys
        {
            public const string CompanyId = "http://www.bovespa.com.br/sinacor/identity/companyId";
            public const string UserId = "http://www.bovespa.com.br/sinacor/identity/userid";
            public const string LoginName = "http://www.bovespa.com.br/sinacor/identity/loginname";
            public const string Password = "http://www.bovespa.com.br/sinacor/identity/password";
        }

        /// <summary>
        /// Criar os dados de Authorização a partir de um dicionário de dados 
        /// </summary>
        /// <param name="data">Dicionário contendo as informações base para criar o objeto com os dados de authorização</param>
        /// <returns>Objeto com os dados de autorização do sinacor</returns>
        internal static SinacorAuthenticationData CreateAuthenticationData(Dictionary<string, object> data)
        {
            SinacorAuthenticationData ret = new SinacorAuthenticationData();

            ret.CompanyId = Convert.ToInt32(data[DataKeys.CompanyId]);
            ret.UserId = Convert.ToInt32(data[DataKeys.UserId]);
            ret.LoginName = Convert.ToString(data[DataKeys.LoginName]);
            ret.Password = Convert.ToString(data[DataKeys.Password]);
            ret.ModuleId = System.Configuration.ConfigurationManager.AppSettings["ModuleId"];

            RetrieveCompanyDetails(ret);

            return ret;
        }

        internal static SinacorAuthenticationData CreateAuthenticationData(ProcessConfigurationSection processConfiguration)
        {
            if (processConfiguration == null)
                return null;
            else
            {
                int companyId = 0;
                string loginName = null, password = null;

                companyId = processConfiguration.AuthenticationConfiguration.CompanyId;
                loginName = processConfiguration.AuthenticationConfiguration.LoginName;
                password = processConfiguration.AuthenticationConfiguration.Password;

                if (companyId > 0 && !string.IsNullOrEmpty(loginName) && !string.IsNullOrEmpty(password))
                {
                    SinacorAuthenticationData ret = new SinacorAuthenticationData();

                    ret.CompanyId = companyId;
                    ret.LoginName = loginName;
                    ret.Password = password;
                    ret.ModuleId = System.Configuration.ConfigurationManager.AppSettings["ModuleId"];
                    
                    AccessControl ac = new AccessControl();
                    User user = ac.RetrieveUser(loginName);
                    if (user != null)
                        ret.UserId = user.Id;
                    

                    RetrieveCompanyDetails(ret);

                    return ret;
                }
                else
                {
                    return null;
                }
            }
        }

        private static void RetrieveCompanyDetails(SinacorAuthenticationData ret)
        {
            try
            {
                ret.CompanyName = string.Empty;
                ret.CompanyCGC = string.Empty;

                AccessControl ac = new AccessControl();
                Company c = ac.RetrieveCompany(ret.CompanyId);
                if (c != null)
                {
                    ret.CompanyName = c.Name;
                    ret.CompanyCGC = c.CGC;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Could not possible to retrieve the company information. See the inner exception for more details.", ex);
            }
        }
    }
}
